#!/usr/bin/env python
# -*- coding:utf-8 _*-

from __future__ import print_function

import os
import sys
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
import matplotlib.pyplot as plt
import seaborn as sns

analyPath = os.getcwd()
plt.rcParams["font.family"] = "Times New Roman"
plt.rcParams["font.size"] = 10.5
degree = int(sys.argv[1]) if len(sys.argv) > 1 else 3
samplePoints = int(sys.argv[3]) if len(sys.argv) > 3 else 11


class Train_CV_SGBRT(object):

    def __init__(self):
        self.data_path = analyPath + "/data"

    def analy(self):

        data = pd.read_csv(os.path.join(self.data_path, str(self.algorithm_name) + ".csv"))
        importance = pd.read_csv(os.path.join(analyPath + '/result/importance', str(self.algorithm_name)), sep=',')
        importance = importance[['Linear_iso']].values
        configNum = data.shape[1] - 1
        events_name = data.columns
        data = pd.DataFrame(data.values)

        interactions = np.zeros((configNum, configNum), dtype=float)
        Linear = LinearRegression()
        for i in range(configNum):
            sortsmain = pd.DataFrame(set(data[i]))
            for j in range(configNum):
                if (i != j and importance[j][0] >= 0.01):
                    ytest = []
                    ydiff = []
                    for k in range(len(sortsmain)):
                        datatmp = data[data[i] == sortsmain[0][k]]
                        if datatmp.shape[0] < 5:
                            continue
                        mainpredict = np.mean(datatmp[configNum])
                        sortssub = pd.DataFrame(set(datatmp[j]))
                        if len(sortssub) > 1:
                            degreesub = min(len(sortssub) - 1, degree)
                            quadratic_featurizer = PolynomialFeatures(degree=degreesub)
                            Xtest = np.linspace(sortssub.min()[0], sortssub.max()[0], samplePoints).reshape(-1, 1)
                            Xtest = quadratic_featurizer.fit_transform(Xtest)
                            X = quadratic_featurizer.fit_transform(datatmp[[j]])
                            Linear.fit(X, datatmp[configNum])
                            Linear.intercept_ = Linear.intercept_ / mainpredict
                            Linear.coef_ = Linear.coef_ / mainpredict
                            ytest.append(Linear.predict(Xtest))
                            if degreesub > 0:
                                Linear.intercept_ = Linear.coef_[1]
                                for m in range(1, degreesub):
                                    Linear.coef_[m] = Linear.coef_[m + 1] * (m + 1)
                                Linear.coef_[degreesub] = 0
                                ydiff.append(Linear.predict(Xtest) * (sortssub.max()[0] - sortssub.min()[0]))
                            else:
                                ydiff.append(np.zeros((samplePoints), dtype=float))
                    if ytest == []:
                        ytest.append(np.zeros((samplePoints), dtype=float))
                        ydiff.append(np.zeros((samplePoints), dtype=float))
                    interactiontmp = 0
                    ytest = pd.DataFrame(ytest)
                    ydiff = pd.DataFrame(ydiff)
                    for k in range(samplePoints):
                        interactiontmp += np.var(ytest[:][k])
                        interactiontmp += np.var(ydiff[:][k])
                    interactions[i][j] = interactiontmp / samplePoints

        interactions = pd.DataFrame(interactions)
        interactions.index = events_name[0:configNum]
        interactions.columns = events_name[0:configNum]
        interactions.to_csv(analyPath + '/result/interaction/' + str(self.algorithm_name))

        plt.figure(figsize=(configNum * 0.2 + 2, configNum * 0.2), frameon=False)
        sns.heatmap(data=interactions, annot=False, xticklabels=events_name[0:-1], yticklabels=events_name[0:-1], annot_kws={'size': 10.5, 'weight': 'normal', 'color': '#66ccff'}, fmt='.0f')
        plt.tight_layout()
        plt.savefig(analyPath + '/result/interaction/' + str(self.algorithm_name) + '.pdf')

    def build(self, item):
        self.algorithm_name = item.replace(".csv", "")
        self.analy()

    def build_loop(self):
        path_list = os.listdir(self.data_path)
        for i in path_list:
            if i != ".gitignore":
                self.algorithm_name = i.replace(".csv", "")
                print(self.algorithm_name)
                self.analy()


if __name__ == '__main__':
    train_cv_sgbrt = Train_CV_SGBRT()
    train_cv_sgbrt.__init__()
    if len(sys.argv) > 2 and sys.argv[2] != 'all':
        train_cv_sgbrt.build(sys.argv[2])
    else:
        train_cv_sgbrt.build_loop()
